Skip to content

JSDoc generated v2 reference docs#1481

Open
LadyBluenotes wants to merge 6 commits intomainfrom
v2-docs-update
Open

JSDoc generated v2 reference docs#1481
LadyBluenotes wants to merge 6 commits intomainfrom
v2-docs-update

Conversation

@LadyBluenotes
Copy link
Copy Markdown
Member

No description provided.

Co-authored-by: Copilot <copilot@github.com>
@bolt-new-by-stackblitz
Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 28, 2026

Deploy Preview for solid-docs ready!

Name Link
🔨 Latest commit 606c677
🔍 Latest deploy log https://app.netlify.com/projects/solid-docs/deploys/69f259749f505300080b2a78
😎 Deploy Preview https://deploy-preview-1481--solid-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@ryansolid
Copy link
Copy Markdown
Member

ryansolid commented Apr 29, 2026

Solid 2.0 reference docs — categorization pass

Re: solid-docs PR #1481.

The auto-generation script visits every public export and emits a page per symbol. That correctly captures the tarball's export surface, but the export surface is wider than the user-facing API — it also includes:

  • Compiler-emitted helpers that ship as exports because the JSX/SSR transform inserts calls to them. Users never call these directly.
  • Internal coordination symbols (hydration plumbing, dev hooks, branded type tags) that exist for internal cross-package wiring.
  • Type aliases that document API parameters, which are better folded into the API pages they describe than rendered as standalone pages.
  • Genuinely advanced/low-level primitives that are public but should be navigationally separate from the canonical surface.

Categorization below is the disposition I'd recommend per export. Three buckets:

  • Canonical — full reference page; surfaced in the primary navigation.
  • Advanced — full reference page; collapsed under an "Advanced / Low-level" subgroup so it doesn't crowd the main nav.
  • Hidden — should not have a page; either internal, compiler-emitted, or better folded into a related page.

Recommended category split

Six top-level reference categories + one collapsible "Advanced". Maps to the structure of the canonical packages/solid/CHEATSHEET.md (shipped in the npm tarball as a one-page reference) so the on-site reference and the in-tarball cheatsheet reinforce the same mental model.

Reference/
├── Reactivity/                  ← signals, effects, transitions
├── Stores/                      ← stores, projections, store helpers
├── Lifecycle & Actions/
├── Components & Context/        ← component types + component-shape APIs
├── Components (JSX)/            ← <For>, <Show>, <Errored>, etc.
├── Rendering & SSR/             ← @solidjs/web entry points
└── Advanced / Low-level/        (collapsed)
    ├── Owner & introspection
    ├── Specialized reactivity & tracking
    ├── Store advanced
    ├── JSX component primitives
    ├── Manual hydration
    └── Interop & async

The PR's current split (actions/, basic-reactivity/, component-apis/, components/, reactive-utilities/, rendering/, secondary-primitives/, store-utilities/, _unmapped/) is close, but: actions/ is small enough to fold into Lifecycle & Actions alongside onSettled; secondary-primitives/ mixes one canonical entry (onSettled) with advanced primitives (createRoot, createRenderEffect, createReaction, createTrackedEffect, onCleanup, resolve) and should split (see recommendation #3); _unmapped/ is mostly internal symbols, type aliases that fold into other pages, or canonical APIs the script's ROUTES table missed.


Per-export disposition

Canonical reference pages (full doc, primary nav)

Reactivity

  • createSignal, createMemo, createEffect
  • createOptimistic — optimistic counterpart of createSignal (Signal<T>); pairs with action
  • untrack, flush, latest
  • isPending

Stores

  • createStore, createProjection, createOptimisticStore
  • reconcile, merge, omit

Lifecycle & Actions

  • onSettledcanonical lifecycle primitive; this is where component-level setup/teardown lives in 2.0 (return cleanup from the body)
  • action, refresh

Components & Context

  • children, createContext, useContext
  • lazy, dynamic (function form — canonical), createUniqueId
  • Component types are documented inline on the Component types page (don't split each into its own — see "Type pages" below)

Components (JSX)

  • <For>, <Show>, <Switch> / <Match> (one combined page is correct in the PR)
  • <Errored>, <Loading>
  • <Repeat>, <Reveal>
  • <Portal> (from @solidjs/web)
  • <Dynamic> (from @solidjs/web) — convenience JSX wrapper for dynamic(). Page can stay combined with dynamic() but the canonical framing leads with the function form (stable Component identity, composes with lazy() and routing).

Rendering & SSR

  • render, hydrate
  • renderToString, renderToStringAsync, renderToStream
  • isServer, isDev (build-time constants — short pages each, or one combined page)

Advanced (full page, collapsed group)

This bucket aligns with the "Advanced / escape hatches" section of packages/solid/CHEATSHEET.md. Where the cheatsheet places an API, the reference docs follow.

Owner & introspection

  • getOwner, runWithOwner, createRoot
  • getObserver, isDisposed

createRoot is the right answer for tests / library setup / non-render entry points but is advanced from an app-author perspective (render() creates the root for normal app code). Cross-link prominently from a Testing guide if/when one exists.

Specialized reactivity & tracking

  • createRenderEffect — render-phase synchronous effect; for DOM bindings during render. App code uses createEffect.
  • createReaction — escape-hatch fine-grained tracking; library use
  • createTrackedEffect — specialized effect type
  • onCleanup — reactive cleanup inside computations. Component-level setup-and-teardown belongs on onSettled (returning a cleanup); onCleanup is for primitive/library internals where the cleanup is tied to a reactive run.
  • isRefreshing — refresh-cycle introspection; almost never needed in app code.

Store advanced

  • deep — opt-in deep tracking for "react to any nested store change" effects; default store tracking is property-level.
  • snapshot — plain (non-reactive) deep copy. For serialization (JSON, localStorage, network) and tests; reactive scopes should read individual values instead.
  • storePath — 1.x-style path setter compat. Use only when migrating; draft-first is canonical.
  • isWrappable — predicate "would createStore wrap this value?". For library authors building store-aware utilities; rare in app code.

JSX component primitives

The function/primitive forms underlying the canonical JSX components. App code uses the JSX form; the primitives exist for library authors, custom universal renderers, and programmatic composition.

  • mapArray — keyed-list reconciler underlying <For>
  • repeat — range iterator underlying <Repeat>
  • createErrorBoundary — primitive form of <Errored>
  • createLoadingBoundary — primitive form of <Loading>
  • createRevealOrder — primitive form of <Reveal>

Manual hydration

  • <NoHydration>, <Hydration> — opt-out / opt-back-in coordination

Interop & async

  • enableExternalSource — bridge non-Solid signal sources
  • flatten — children-helper internal; children() covers the common case
  • resolve — await a reactive value as a promise; testing/integration use
  • NotReadyError — error type; caught manually in advanced cases

Diagnostics & dev hooks

  • DEV — dev hook bag (emitDiagnostic, graph registration, etc.) consumed by tooling — solid-devtools, AI-readiness instrumentation, and lint-rule runtime probes. Public for tooling integrations; not for app code. Worth a page so tooling authors have a stable reference for what hooks are available and what they emit.

Hidden (no page)

Internal symbols / brands — pure cross-package wiring, never user-called:

  • $PROXY, $REFRESH, $TRACK, $DEVCOMP

Compiler-emitted, never user-called — every page generated for these is misleading because hand-written code doesn't reach for them:

  • JSX/SSR compiler emissions: ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, escape, resolveSSRNode
  • JSX runtime helpers: createComponent, mergeProps (the @solidjs/web re-export of merge that the JSX transform calls when compiling prop spreads — not a user-facing API; users call merge directly)
  • DOM op helpers (in @solidjs/web): getNextElement, insert, spread, template, Namespaces, SVGElements, MathMLElements, addEventListener, etc. — none of the dom-expressions DOM ops belong in user docs; they're the JSX transform's runtime.

Internal coordination — public for cross-package, not for users:

  • sharedConfig, enableHydration, getNextChildId, NoHydrateContext
  • enforceLoadingBoundary — only render() calls this to toggle the dev-mode enforcement window
  • ssrHandleError, ssrRunInScope (stubs / internal)
  • createDeepProxy (server internal)
  • getNextElement (hydration internal)
  • getContext, setContext (@solidjs/signals) — low-level owner-targeted context primitives that solid-js's createContext / useContext wrap. The user-facing context API is createContext / useContext (canonical, in solid-js); these primitives are exposed for cross-package wiring (e.g. the hydration-aware context plumbing).
  • createOwner — low-level primitive that creates a bare owner node. Used by framework internals to group cleanups (the JSDoc itself flags this). User-facing entry points are createRoot (canonical from a "host a reactive scope outside a component" angle) and runWithOwner (re-enter a captured owner).

Document inline on the consuming API page (no standalone page)

Mostly types (interfaces / type aliases) that exist purely to type a parameter, option bag, or return value of an API; one runtime helper (isEqual) is included because its only meaningful use is being passed to one of those option bags. "Fold in" here just means: don't render a separate reference page; document the fields / shape / function inline on the API page that consumes it.

Symbol Documented on
StoreSetter createStore
StoreOptions createStore
ProjectionOptions createProjection (and the projection form of createStore)
HydrationProjectionOptions createProjection (Hydration section)
StorePathRange, Part, PathSetter, ArrayFilterFn storePath
Refreshable createOptimisticStore (with a one-line cross-link from createProjection and the projection form of createStore)
EffectOptions, EffectFunction, ComputeFunction createEffect
MemoOptions, SignalOptions createMemo / createSignal
isEqual createMemo / createSignal (the equals field paragraph — it's the default reference-equality function)
ExternalSource, ExternalSourceConfig, ExternalSourceFactory enableExternalSource

Standalone Types pages worth keeping (they're cross-cutting structural types):

  • Accessor, Setter, Signal
  • Component, ParentComponent, VoidComponent, FlowComponent + the matching *Props types — one combined "Component types" page reads better than seven
  • ComponentProps, Ref
  • Context, ContextProviderComponent
  • Store, StoreNode, SolidStore
  • Owner
  • JSX, JSXElement

Disposition for the PR's _unmapped/ items specifically

_unmapped/ page in PR Disposition
create-error-boundary Advanced → JSX component primitives (paired with <Errored>)
create-loading-boundary Advanced → JSX component primitives (paired with <Loading>)
create-reveal-order Advanced → JSX component primitives (paired with <Reveal>)
create-owner Hidden — framework-internal primitive for grouping cleanups. The user-facing entry points are createRoot (host a reactive scope outside a component) and runWithOwner (re-enter a captured owner).
enable-external-source Advanced → Interop & async
flatten Advanced → Interop & async (or hide; children() covers the common case)
get-context Hidden@solidjs/signals low-level primitive that useContext wraps. The canonical user-facing API is useContext (in solid-js).
set-context Hidden@solidjs/signals low-level primitive that createContext's provider wraps. The canonical user-facing API is createContext (in solid-js).
hydration (the <Hydration> component) Advanced → Manual hydration
is-disposed Advanced → Owner & introspection
merge-props Hidden@solidjs/web mergeProps is the dom-expressions compiler helper for prop spreads emitted by the JSX transform; not user-facing. Users call merge (in solid-js) directly.
projection-options Fold into createProjection
refreshable Fold into createOptimisticStore (with cross-links)
store-options Fold into createStore
store-setter Fold into createStore

Cross-cutting recommendations

  1. The export-surface ≠ doc-surface. A non-trivial slice of public exports is compiler-emitted or internal-coordination. The Hidden-bucket exports listed above are tagged @internal in source — covering the ssr* / DOM-op compiler primitives in @solidjs/web/server-mock, the mergeProps re-export, the brand symbols ($PROXY, $REFRESH, $TRACK, $TARGET, $DELETED, $DEVCOMP), the cross-package wiring (getContext / setContext from signals, createOwner, getNextChildId / peekNextChildId, enforceLoadingBoundary, sharedConfig, enableHydration, NoHydrateContext), and the ssrHandleError / ssrRunInScope stubs. The doc-generator script can drive its hidelist off that JSDoc tag — keeps ROUTES focused on what should render, and the convention lives next to the export so adding a new internal symbol doesn't silently land a docs page.

  2. Type pages should default to inlined. A standalone store-setter page with a 3-line type alias is worse than the same content under the "Types" section of createStore, where it's read in context. Suggest the script have a "fold into" mapping for type aliases: { StoreSetter: "createStore", … }.

  3. secondary-primitives/ should split. onSettled is canonical (and the canonical 2.0 lifecycle primitive — see point 4). The rest of the current secondary-primitives/ set — createRoot, createRenderEffect, createReaction, createTrackedEffect, onCleanup, resolve — are all advanced. The "secondary" framing is a 1.x carry-over from when createMemo/createSignal were "primary"; in 2.0 the right split is canonical-vs-advanced, not primary-vs-secondary.

  4. onCleanup page warning. It's still public and supported, but the canonical 2.0 lifecycle is onSettled returning a cleanup. The page should open with a callout to that effect (matches the JSDoc that ships on onCleanup / onSettled in @solidjs/signals). Otherwise readers will keep using onCleanup for component cleanup out of React-useEffect muscle memory and miss that onSettled is the better default.

  5. @solidjs/web-vs-solid-js separation. Portal, Dynamic, render, hydrate, isServer, isDev, and the SSR renderTo* family are all on @solidjs/web. The reference pages can stay co-located, but the import path in each example should match — the auto-generator likely needs a per-symbol package map to render import { … } from "@solidjs/web" vs "solid-js" correctly.


JSDoc example coverage

Every Canonical and Advanced symbol enumerated above has an @example block in source. Examples use the @example tag uniformly across the surface — the JSX components (<For>, <Repeat>, <Switch>, <Errored>, <Reveal>, dynamic() / <Dynamic>) and the @solidjs/web build-time constants (isServer, isDev) are aligned with the rest. The doc generator can extract examples by walking @example tags only and produce uniform snippet rendering.

Forward-looking maintenance. Have the doc-generator script (or a preflight check in CI) fail when a page is emitted for a non-@internal Canonical/Advanced symbol whose JSDoc lacks an @example. That keeps the coverage from regressing as the surface evolves and surfaces missing examples at PR review time rather than at docs-publish time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants